package com.cntaiping.royal.bass.system.common;

import com.cntaiping.royal.bass.system.service.RedisUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author jiangwei
 * @since 19/2/20
 */
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

    @Value(value = "${spring.redis.pool.max.idle}")
    private int maxIdle;

    @Value(value = "${spring.redis.pool.min.idle}")
    private int minIdle;

    @Value(value = "${spring.redis.pool.max.active}")
    private int active;

    @Value(value = "${spring.redis.pool.max.wait}")
    private int wait;

    @Value(value = "${spring.redis.port}")
    private int port;

    @Value(value = "${spring.redis.host}")
    private String host;

    @Value(value = "${spring.redis.password}")
    private String password;

    @Value(value = "${spring.redis.database}")
    private int database;

    @Value(value = "${spring.redis.timeOut}")
    private int redisTimeOut;


    /***
     * JedisPoolConfig连接池
     *
     * @return
     */
    @Bean
    public JedisPoolConfig jedisPoolConfig() {
        JedisPoolConfig jedisPoolConfig = null;
        try {
            jedisPoolConfig = new JedisPoolConfig();
            jedisPoolConfig.setMaxIdle(maxIdle);
//            jedisPoolConfig.setMaxTotal(maxTotal);
            jedisPoolConfig.setMinIdle(minIdle);
            jedisPoolConfig.setMaxWaitMillis(wait);
//            jedisPoolConfig.setTestOnBorrow(false);
        } catch (Exception e) {
//            log.error("jedisPoolConfig有问题", e);
        }
        return jedisPoolConfig;
    }

    /***
     * 配置工厂
     * @param jedisPoolConfig
     * @return
     */
    @Bean
    public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig) {
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(jedisPoolConfig);

        jedisConnectionFactory.setHostName(host);
        jedisConnectionFactory.setPort(port);
        if(password != null && !password.isEmpty()){
            jedisConnectionFactory.setPassword(password);
        }

        jedisConnectionFactory.setTimeout(redisTimeOut);
        jedisConnectionFactory.setDatabase(database);
        return jedisConnectionFactory;

    }

    /***
     * 实例化RedisTemplate 对象
     * @param jedisConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<String, String> redisTemplate(JedisConnectionFactory jedisConnectionFactory) {
        RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(jedisConnectionFactory);
        return redisTemplate;

    }

    /***
     * 设置数据存入redis的序列化方式,并开启事物
     * @param redisTemplate
     * @param factory
     */
    private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory){

        /***
         * 设置序列化
         * 如果不设置,那么在用实体(为序列化)进行存储时,会提示错误:Failed to serialize object using DefaultSerializer;
         *
         */
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());

        //开启事物
        redisTemplate.setEnableTransactionSupport(true);
        //将连接工厂设置到模板中
        redisTemplate.setConnectionFactory(factory);
    }

    @Bean
    public CacheManager cacheManager(RedisTemplate<String, Object> redisTemplate){
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        cacheManager.setDefaultExpiration(3000);
        Map<String, Long> expires = new ConcurrentHashMap<>();
        cacheManager.setExpires(expires);
        return cacheManager;
    }

    @Bean(name = "redisUtil")
    public RedisUtil redisUtil(RedisTemplate<String, Object> redisTemplate){
        RedisUtil redisUtil = new RedisUtil();
        redisUtil.setRedisTemplate(redisTemplate);

        return redisUtil;
    }
}


